/*
 * Activitats.java
 *
 */

package org.wooxes.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FormHandler;
import com.google.gwt.user.client.ui.FormSubmitEvent;
import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.Window;
import java.util.Date;
import java.util.Vector;

public class Activitats extends Sink {
    
    public static SinkInfo init() {
        return new SinkInfo("Activitats", "Llista d'activitats") {
            public Sink createInstance() {
                return new Activitats();
            }
        };
    }
    
    final String TXT_ERROR_BD = "Error: No es pot conectar amb la base de dades";
    final String TXT_LOADING = "Carregant...";
    Label lblcarregant;

    SimplePanel contenedor;
    Panel anterior_llista_activitats;
    Panel anterior_llista_arxius;
    Widget[] historial = new Widget[3];
    
    public Activitats() {
        VerticalPanel vp = new VerticalPanel();
        vp.setWidth("100%");

        
        /*
         * contenedor
         * 
         * Widget que contindrà els diversos panels
         */
        contenedor = new SimplePanel();
        contenedor.addStyleName("Contenedor");

        lblcarregant = new Label(TXT_LOADING);
        lblcarregant.setStyleName("Label-Carregant");

        /*
         * hpSeleccio
         * 
         * Desplegable per seleccionar Assignatura
         */
        final SimplePanel hpSeleccio = new SimplePanel();
        hpSeleccio.setStyleName("mostrarAssignatures-PanelSeleccio");
        vp.add(hpSeleccio);

        vp.add(lblcarregant);
        vp.add(contenedor);
        
        // Es llança el servei. S'enumeren les assignatures
        getService().getAssignatures(mostrarAssignatures(hpSeleccio));
        initWidget(vp);
    }
    
    private FlexTable crearActivitatsFlexTable(String s){
        //Creació del contingut
        FlexTable flex = new FlexTable();

        flex.setStyleName("mostrarActivitats-FlexTable");
        
        //Creació de la capçalera o header
        flex.setWidget(0, 0, new Label(s));
        flex.getRowFormatter().setStyleName(0, "mostrarActivitats-FlexTable-Header");
        flex.getFlexCellFormatter().setColSpan(0, 0, 4);
        flex.setWidget(1, 1, new Label("Títol"));
        flex.setWidget(1, 2, new Label("Estat"));
        flex.setWidget(1, 3, new Label("Límit"));
        flex.getFlexCellFormatter().setWidth(1, 0, "25px");

        // El Títol té amplada lliure
        // flex.getFlexCellFormatter().setWidth(1, 1, "50%");
        flex.getFlexCellFormatter().setWidth(1, 2, "20%");
        flex.getFlexCellFormatter().setWidth(1, 3, "20%");
        flex.getRowFormatter().setStyleName(1, "mostrarActivitats-FlexTable-Header");
        
        return flex;
    }
    
    private AsyncCallback mostrarAssignatures(final Panel panelSeleccio){
        return new AsyncCallback() {
            public void onSuccess(Object result) {
                Vector v = (Vector) result;
                if( v == null ){
                    contenedor.setWidget(new Label(TXT_ERROR_BD));
                    return;
                }
                else if( v.size() == 0 ){
                    contenedor.setWidget(new Label("No s'ha trobat cap assignatura"));
                    return;
                }
                final ListBox listSeleccio = new ListBox();
                listSeleccio.setStyleName("mostrarAssignatures-LlistaSeleccio");
                
                for(int i=0; i< v.size(); i++){
                    Assignatura aux = (Assignatura) v.get(i);
                    listSeleccio.addItem(aux.getNom());
                }

                Button buttonAnar = new Button("Anar");

                buttonAnar.addClickListener(new ClickListener(){
                   public void onClick(Widget w) {
                        int index = listSeleccio.getSelectedIndex();
                        final String st = listSeleccio.getValue(index);
                        lblcarregant.setVisible(true);
                        getService().getActivitats(st, mostrarActivitats(st));
                   }
                });
                
                HorizontalPanel hp = new HorizontalPanel();
                hp.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);

                hp.add(listSeleccio);
                hp.add(buttonAnar);
                
                lblcarregant.setVisible(false);
                contenedor.setWidget(new Label("Selecciona alguna assignatura"));
                panelSeleccio.add(hp);
                
            }
            public void onFailure(Throwable caught) {
                onSuccess(null);
            }
        };
    }

    private AsyncCallback mostrarActivitats(final String st){
        return new AsyncCallback() {
                    public void onSuccess(Object result) {
                        // S'inicialitzen els camps "anterior" i "anterior_arxiu"
                        // ja que no es tornaran a utilitzar
                        anterior_llista_activitats = null;
                        anterior_llista_arxius = null;
                        
                        // Inici
                        Vector v = (Vector) result;
                        final FlexTable flex = crearActivitatsFlexTable(st);
                        int pos = flex.getRowCount();
                        if( v == null ){
                            flex.setWidget(pos, 1, new Label(TXT_ERROR_BD));
                            lblcarregant.setVisible(false);
                            contenedor.setWidget(flex);
                            return;
                        }
                        else if(v.isEmpty() ){
                            flex.setWidget(pos, 1, new Label("No hi ha cap activitat"));
                            lblcarregant.setVisible(false);
                            contenedor.setWidget(flex);
                            return;
                        }
                        pos--;
                        for(int i=0; i< v.size(); i++){
                            pos++;
                            final Activitat ac = (Activitat) v.get(i);

                            //Es guarda a la taula
                            Label link = new Label(ac.getNom());
                            link.setStyleName("mostrarActivitats-FlexTable-Titol");
                            link.addStyleName("link");
                            link.addClickListener(new ClickListener(){
                                public void onClick(Widget sender) {
                                    lblcarregant.setVisible(true);
                                    mostrarInfoActivitat(ac, st);
                                    
                                }
                            });
                            
                            //S'inserta imatge "carpeta tancada"
                            ImageDir imatge = new ImageDir();
                            imatge.setStyleName("link");
                            imatge.addClickListener(new ClickListener(){
                                public void onClick(Widget sender) {
                                    ImageDir img = (ImageDir) sender;
                                    FlexTable flex = (FlexTable) img.getParent();
                                    int index = img.getIndex();                                    
                                    if(!img.isOpen()){
                                        img.setOpen(true);
                                        lblcarregant.setVisible(true);
                                        
                                        getService().getEntregues(
                                                ac.getId(),
                                                mostrarEntregues(flex, index));
                                    }
                                    else{
                                        img.setOpen(false);
                                        Widget aux = null;
                                        borrarFiles(flex,index);
                                    }
                                }
                            });
                            
                            flex.setWidget(pos, 0, imatge);
                            //Es crea el hp per a que "link" no ocupi tota la cel·la
                            HorizontalPanel hp = new HorizontalPanel();
                            hp.add(link);
                            flex.setWidget(pos, 1, hp);

                            Label estat = new Label();
                            estat.setStyleName("mostrarActivitats-FlexTable-Estat");
                            if( new Date().before(ac.getData())){
                                estat.setText("Obert");
                                estat.addStyleDependentName("Obert");
                            }
                            else{
                                estat.setText("Tancat");
                                estat.addStyleDependentName("Tancat");
                            }
                            flex.setWidget(pos, 2, estat);
                            
                            Label limit = new Label(ac.getFormattedData());
                            limit.setStyleName("mostrarActivitats-FlexTable-Limit");
                            flex.setWidget(pos, 3, limit);
                        }
                        lblcarregant.setVisible(false);
                        contenedor.setWidget(flex);
                    }
                    public void onFailure(Throwable caught) {
                        onSuccess(null);
                    }
                };
    }
    
    private void mostrarInfoActivitat(final Activitat ac, final String nom_assignatura){
        lblcarregant.setVisible(true);
        VerticalPanel vp = new VerticalPanel();
        vp.setStyleName("mostrarInfoActivitat-vp");
        
        Panel vpTitol;
        Panel vpEstat;
        Panel vpLimit;
        Panel vpDescripcio;
        Panel vpAdjunts;
        
        //Titol
        vpTitol = crearApartat("Títol", ac.getNom(), null);
        //Estat
        final String estat;
        if( new Date().before(ac.getData()) ){
            estat = "Obert";
        }
        else{
            estat = "Tancat";
        }
        vpEstat = crearApartat("Estat", estat, null);
        //Limit
        vpLimit = crearApartat("Límit", ac.getFormattedData(), null);
        //Descripció
        vpDescripcio = crearApartat("Descripció", ac.getDescripcio(), "html");
        //vpAdjunts
        vpAdjunts = crearApartat("Adjunt", ac.getAdjunt(), Integer.toString(ac.getId()));
        
        Label enviar = new Label("Enviar activitat");
        enviar.setStyleName("mostrarInfoActivitat-Enviar");
        enviar.addStyleName("link");
        enviar.addClickListener(new ClickListener(){
            public void onClick(Widget sender) {
                        if( estat.equals("Tancat") ){
                            // POPUP 
                            PopupPanel p = new PopupPanel(true);
                            HTML missatge = new HTML();
                            missatge.setHTML("Fora del termini establert: <br />" +
                                             "No es pot enviar l'arxiu");
                            missatge.setStyleName("Popup-ForaTermini");

                            p.setWidget(missatge);
                            int left = sender.getAbsoluteLeft() + 30;
                            int top = sender.getAbsoluteTop() + 10;
                            p.setPopupPosition(left, top);
                            p.show();
                        }
                        else{
                            EnviarActivitat enviarDialog = new EnviarActivitat(ac.getNom(),ac.getId());
                            enviarDialog.show();
                        }
            }
        });

        HorizontalPanel hpenviar = new HorizontalPanel();
        hpenviar.add(enviar);
        
        Button enrere = new Button("Enrere");
        enrere.addClickListener(new ClickListener(){
            public void onClick(Widget sender) {
                lblcarregant.setVisible(true);
                getService().getActivitats(nom_assignatura, mostrarActivitats(nom_assignatura));
                                    
            }
        });
        enrere.addStyleDependentName("Tancar");
        
        vp.add(vpTitol);
        vp.add(vpEstat);
        vp.add(vpLimit);
        vp.add(vpDescripcio);
        vp.add(vpAdjunts);
        vp.add(hpenviar);
        vp.add(enrere);
        
        lblcarregant.setVisible(false);
        contenedor.setWidget(vp);
    }
    
    private AsyncCallback mostrarEntregues(final FlexTable flex, final int s_indice){
        return new AsyncCallback() {
            public void onSuccess(Object result) {
                Vector v = (Vector) result;
                int index = s_indice + 1;
                if( v == null){
                    flex.insertRow(index);
                    Label label = new Label(TXT_ERROR_BD);
                    label.addStyleName("mostrarActivitats-NomEntrega");
                    flex.setWidget(index, 1, label);
                    lblcarregant.setVisible(false);
                    return;
                }
                else if( v.size() == 0){
                    flex.insertRow(index);
                    Label label = new Label("No s'ha efectuat cap entrega");
                    label.addStyleName("mostrarEntregues-Titol");
                    flex.setWidget(index, 1, label);
                    lblcarregant.setVisible(false);
                    return;
                }

                for(int i=0; i< v.size(); i++){
                    final Entrega en = (Entrega) v.get(i);
           
                    Label titol = new Label(en.getArxiu());
                    titol.setStyleName("mostrarEntregues-Titol");
                    titol.addStyleName("link");
                    

                    titol.addClickListener(new ClickListener(){
                        public void onClick(Widget sender) {
                            anterior_llista_activitats = flex;
                            lblcarregant.setVisible(true);
                            getService().getLlistaArxius(
                                        en.getId(),
                                        mostrarInfoEntrega(en));
                        }
                    });
                            
                    HorizontalPanel hptitol = new HorizontalPanel();
                    hptitol.add(titol);
                    
                    Label alumne = new Label(en.getAlumne());
                    alumne.setStyleName("mostrarEntregues-Alumne");
                    
                    flex.insertRow(index+i);
                    flex.setWidget(index+i, 1, hptitol);
                    flex.setWidget(index+i, 2, alumne);
                    flex.getFlexCellFormatter().setColSpan(index+i,2,2);
                }
                lblcarregant.setVisible(false);
            }
            public void onFailure(Throwable caught) {
                onSuccess(null);
            }
        };
    }
    
    private AsyncCallback mostrarInfoEntrega(final Entrega en){
        return new AsyncCallback() {
            public void onSuccess(Object result) {
                Vector v = (Vector) result;
                
                VerticalPanel vp = new VerticalPanel();
                vp.setStyleName("mostrarInfoEntrega-vp");
                
                
                Button enrere = new Button("Enrere");
                enrere.addClickListener(new ClickListener(){
                    public void onClick(Widget sender) {
                        contenedor.setWidget(anterior_llista_activitats);
                                    
                    }
                });
                
                if( v == null){
                    vp.add(new Label(TXT_ERROR_BD));
                    vp.add(enrere);
                    lblcarregant.setVisible(false);
                    contenedor.setWidget(vp);
                    return;
                }
                else if( v.size() == 0){
                    vp.add(new Label("Error: No es pot llegir l'arxiu " + en.getArxiu()));
                    vp.add(enrere);
                    lblcarregant.setVisible(false);
                    contenedor.setWidget(vp);
                    return;
                }

                FlexTable header = new FlexTable();
                header.setStyleName("mostrarInfoEntrega-Header");
                
                //Alumne
                header.setWidget(0,0, new Label("Alumne:"));
                header.getFlexCellFormatter().setStyleName(0, 0, "mostrarInfoEntrega-Header-Apartat");
                header.setWidget(0,1, new Label(en.getAlumne()));
                header.getFlexCellFormatter().setStyleName(0, 1, "mostrarInfoEntrega-Header-Descripcio");
                
                //Arxiu
                header.setWidget(1,0, new Label("Arxiu:"));
                header.getFlexCellFormatter().setStyleName(1, 0, "mostrarInfoEntrega-Header-Apartat");
                header.setWidget(1,1, new Label(en.getArxiu()));
                header.getFlexCellFormatter().setStyleName(1, 1, "mostrarInfoEntrega-Header-Descripcio");
                
                //Data
                header.setWidget(2,0, new Label("Data entrega:"));
                header.getFlexCellFormatter().setStyleName(2, 0, "mostrarInfoEntrega-Header-Apartat");
                header.setWidget(2,1, new Label(en.getFormattedData()));
                header.getFlexCellFormatter().setStyleName(2, 1, "mostrarInfoEntrega-Header-Descripcio");
                
                vp.add(header);
                
                // Creació de la taula
                FlexTable llista = new FlexTable();
                llista.setStyleName("mostrarInfoEntrega-FlexTable");
                llista.setWidget(0,0,new Label(en.getArxiu()));
                llista.getFlexCellFormatter().setColSpan(0, 0, 3);
                llista.getRowFormatter().setStyleName(0, "mostrarActivitats-FlexTable-Header");
                
                llista.setWidget(1, 1, new Label("Nom"));
                llista.setWidget(1, 2, new Label("Tamany"));
                llista.getFlexCellFormatter().setWidth(1, 0, "25px");
                llista.getFlexCellFormatter().setWidth(1, 2, "100px");
                llista.getRowFormatter().setStyleName(1, "mostrarActivitats-FlexTable-Header");
                
                
                int pos = llista.getRowCount();
                pos--;
                            
                for(int i=0; i<v.size(); i++){
                    pos++;
                    crearArxiuLlista(pos, llista, (Arxiu) v.get(i));
                }
                
                pos++;
                llista.setWidget(pos, 0, enrere);
                llista.getFlexCellFormatter().setColSpan(pos, 0, 3);
                vp.add(llista);
                
                anterior_llista_arxius = vp;
                lblcarregant.setVisible(false);
                contenedor.setWidget(vp);
            }
            public void onFailure(Throwable caught) {
                onSuccess(null);
            }
        };
    }
    
    // Crea els diferents apartats de "mostrarInfoActivitat"
    private Panel crearApartat(String a, String b, String tipo){
        VerticalPanel vp = new VerticalPanel();
        vp.setWidth("100%");
        
        Label apartat = new Label(a + ":");
        apartat.setStyleName("mostrarInfoActivitat-Apartat");
        vp.add(apartat);
        
        if(tipo == null){
            Label contingut = new Label(b);
            contingut.setStyleName("mostrarInfoActivitat-Contingut");
            vp.add(contingut);
        }
        else if( tipo.equals("html")){
            HTML contingut = new HTML(b);
            contingut.setStyleName("mostrarInfoActivitat-Contingut");
            vp.add(contingut);
        }
        if( a.equals("Adjunt")){
            if ( b == null || b.equals("")){
                Label contingut = new Label();
                contingut.setStyleName("mostrarInfoActivitat-Contingut");
                contingut.setText("No s'ha adjuntat cap arxiu");
                vp.add(contingut);
            }
            else{
                HTML contingut = new HTML();
                contingut.setHTML("<a href='descargar_arxiu?id="+tipo+"' title='Descarrega...'>"+b+"</a>");
                contingut.setStyleName("mostrarInfoActivitat-Contingut");
                contingut.addStyleName("link");
                
                // Es crea el hp per evitar que el link sigui de tota la línia
                HorizontalPanel hp = new HorizontalPanel();
                hp.add(contingut);
                
                vp.add(hp);
            }
        }

        return vp;
    }
    
    // Borra les files que ja no s'han de mostrar
    // al amagar les entregues d'una activitat
    private int borrarFiles (FlexTable flex, int index){
        int pos = index+1;
        int borrats = 0;
        boolean continuar = true;
        Widget aux;
        
        while(continuar && (pos < flex.getRowCount())){
            aux = flex.getWidget(pos, 0);
            if (aux == null){
                flex.removeRow(pos);
                borrats++;
            }
            else{
                continuar = false;
            }
        }
        return borrats;
    }
    
    // Crea les files d'una llista d'arxius
    private void crearArxiuLlista(int pos, final FlexTable llista, final Arxiu arxiu){
        String [] ext_txt = {"java", "xml", "html", "cc", "cpp", "txt" };
        String ruta_txt = "images/arxiu_txt.png";
        
        String ruta_pdf = "images/arxiu_pdf.png";
        
        String extensio = arxiu.getNom();
        extensio = extensio.substring(extensio.lastIndexOf(".")+1);
        
        Image imatge = new Image();
        Label nom = new Label(arxiu.getRelatiu());
        nom.setStyleName("mostrarInfoEntrega-Nom");
        nom.addStyleName("link");
        
        Label tamany = new Label(arxiu.getStringSize());
        tamany.setStyleName("mostrarInfoEntrega-Tamany");
        
        boolean isTxt = false;
        int i=0;
        
        // Es recorren totes les extensions que es visualitzaran com a Text.
        // Si és un arxiu de text, es marca com a tal.
        while( i<ext_txt.length && !isTxt){
            if(extensio.equalsIgnoreCase(ext_txt[i])){
                isTxt = true;
            }
            i++;
        }
        
        if(isTxt){
            nom.addClickListener(new ClickListener(){
                public void onClick(Widget sender){
                    //anterior_arxiu = llista;
                    lblcarregant.setVisible(true);
                    getService().getArxiu(
                                 arxiu.getAbsolut(),
                                 mostrarContingutArxiu(arxiu));
                }
            });
            imatge.setUrl(ruta_txt);
        }
        // Si no es tracta d'un arxiu de text
        else{
            nom.addStyleName("no-hand");
            imatge.setUrl(ruta_pdf);
        }
        
        
        llista.setWidget(pos, 0, imatge);
        llista.setWidget(pos, 1, nom);
        llista.setWidget(pos, 2, tamany);
    }

    private AsyncCallback mostrarContingutArxiu(final Arxiu arxiu){
        return new AsyncCallback() {
            public void onSuccess(Object result) {
                Vector v = (Vector) result;
                
                VerticalPanel vp = new VerticalPanel();
                //vp.setStyleName("activitats-Activitat");
                vp.setWidth("100%");
                
                Button enrere = new Button("Enrere");
                enrere.addStyleName("mostrarContingutArxiu-Button");
                enrere.addClickListener(new ClickListener(){
                   public void onClick(Widget sender){
                       contenedor.setWidget(anterior_llista_arxius);
                   }
                });
                vp.add(enrere);
                if( v == null){
                    vp.add(new Label(TXT_ERROR_BD));
                    lblcarregant.setVisible(false);
                    contenedor.setWidget(vp);
                    return;
                }
                else if( v.size() == 0){
                    vp.add(new Label("Arxiu buit"));
                    lblcarregant.setVisible(false);
                    contenedor.setWidget(vp);
                    return;
                }
                
                for(int i=0; i<v.size(); i++){
                    Comment comment = (Comment) v.get(i);
                    
                    FormHandler fh = new FormHandler(){
                        public void onSubmit(FormSubmitEvent event){
                            //Window.alert("enviat");
                            //event.setCancelled(true);
                        }
                        public void onSubmitComplete(FormSubmitCompleteEvent event){
                            String resposta = event.getResults();
                            if (resposta.startsWith("ok")){
                                lblcarregant.setVisible(true);
                                getService().getArxiu(arxiu.getAbsolut(),
                                    mostrarContingutArxiu(arxiu));
                            }
                            else{
                                Window.alert(resposta);
                            }
                        }
                    };

                    Linia linia = new Linia(arxiu.getAbsolut(), i+1, comment, fh);
                    vp.add(linia);
                }
                // Creació de la taula
                
                lblcarregant.setVisible(false);
                contenedor.setWidget(vp);
            }
            public void onFailure(Throwable caught) {
                onSuccess(null);
            }
        };
    }
    
    public static ActivitatsServiceAsync getService(){
        ActivitatsServiceAsync service = (ActivitatsServiceAsync) GWT.create(ActivitatsService.class);
        ServiceDefTarget endpoint = (ServiceDefTarget) service;
        String moduleRelativeURL = GWT.getModuleBaseURL() + "activitatsservice";
        endpoint.setServiceEntryPoint(moduleRelativeURL);
        return service;
    }
    
}